<template>
  <div>
    <!-- 面包屑部分 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片视图 -->
    <el-card>
      <el-row>
        <el-col>
          <el-button type="primary">添加角色</el-button>
        </el-col>
      </el-row>
      <!-- 角色列表 -->
      <el-table :data="rolesList" border stripe style="width: 100%">
        <el-table-column type="expand">
          <template v-slot:default="slotProps">
            <el-row
              :class="['bborder',index1===0?'tboeder':'','tcente']"
              :key="item1.id"
              :index="index1"
              v-for="(item1,index1) in slotProps.row.children"
            >
              <!-- 渲染一级权限 -->
              <el-col :span="5">
                <el-tag closable>{{item1.authName}}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 渲染二级权限和三级权限区域 -->
              <el-col :span="19">
                <el-row
                  :class="[index2===0?'':'tboeder','tcente']"
                  :key="item2.id"
                  :index="index2"
                  v-for="(item2,index2) in item1.children"
                >
                  <!-- 二级权限 -->
                  <el-col :span="5">
                    <el-tag closable type="success">{{item2.authName}}</el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <!-- 三级权限 -->
                  <el-col :span="14">
                    <el-tag
                      closable
                      type="warning"
                      :key="item3.id"
                      :index="index3"
                      v-for="(item3,index3) in item2.children"
                      @close="deleteRight(slotProps.row,item3.id)"
                    >{{item3.authName}}</el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column type="index" label="#"></el-table-column>
        <el-table-column prop="roleName" label="角色名称"></el-table-column>
        <el-table-column prop="roleDesc" label="角色描述"></el-table-column>
        <el-table-column label="操作" width="300px">
          <template v-slot:default="slotProps">
            <el-button
              size="mini"
              type="primary"
              icon="el-icon-edit"
              @click="editRolesButton(slotProps.row)"
            >编辑</el-button>
            <el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button>
            <el-button
              size="mini"
              type="warning"
              icon="el-icon-setting"
              @click="getRightsListsData(slotProps.row)"
            >分配角色</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 分配角色对话框 -->
    <el-dialog title="分配权限" :visible.sync="getRightsDialog" width="50%">
      <el-tree
        :data="rightsList"
        :props="defaultProps"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="defKeys"
        ref="treeRef"
      ></el-tree>
      <span slot="footer">
        <el-button @click="cencelChengeRightsList">取 消</el-button>
        <el-button type="primary" @click="allotRights">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 编辑角色的对话框 -->
    <el-dialog
      title="编辑角色"
      :visible.sync="editDialogVisible"
      width="50%"
      @close="cancelRolesChenge"
    >
      <div>
        <p>当前的角色： {{editrolesObj.roleName}}</p>
        <p>
          分配新角色：
          <el-select v-model="setRoleId" placeholder="请选择">
            <!-- 将角色列表里的数据赋值到每一个option项中 其中label绑定的数据 会显示在选择下拉列表中 -->
            <el-option
              v-for="item in rolesList"
              :key="item.id"
              :label="item.roleName"
              :value="item.id"
            ></el-option>
          </el-select>
        </p>
      </div>
      <span slot="footer">
        <el-button @click="editDialogVisible=false">取 消</el-button>
        <el-button type="primary" @click="confirmRolesChenge()">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 所有角色列表数据
      rolesList: [],
      //   分配权限的数据
      rightsList: [],

      getRightsDialog: false,
      defaultProps: {
        children: 'children',
        label: 'authName'
      },
      //   定义筛选出来的三级权限的列表
      defKeys: [],
      //   将要被分配权限的角色id
      roleId: '',
      id: 0,
      // 定义编辑角色对话框的显示与隐藏
      editDialogVisible: false,
      // 定义编辑对话框中要渲染的角色信息对象
      editrolesObj: {},
      // 角色验证规则
      editRules: {
        roleName: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
        ]
      },
      // 新获取到的角色列表
      // editRolesList: [],
      // 获取到的角色的id
      setRoleId: '',
      // 获取到到的角色的名称
      setRoleName: ''
    };
  },
  created() {
    this.getRolesList();
  },
  methods: {
    //   获取角色列表
    async getRolesList() {
      const data = await this.$http.get('roles');
      console.log(data);
      if (!data) return;
      this.rolesList = data;
      //   console.log(this.rolesList);
    },
    // 根据id删除对应权限
    deleteRight(roles, id) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          console.log(roles.id, id);
          //   console.log(this);
          const data = await this.$http.delete(`roles/${roles.id}/rights/${id}`);
          //   console.log(data);
          if (!data) return;
          roles.children = data;
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
    },
    // 展示权限列表的数据
    async getRightsListsData(role) {
      // 在展示权限列表的数据之前先把当前点击的 角色的ID存储起来
      this.roleId = role.id;
      // 在对话框展示出来之前获取数据
      const data = await this.$http.get('rights/tree');
      if (!data) return;
      this.rightsList = data;
      // 在展示权限列表数据之前 先获取当前被选中节点的key

      // 思路：1.在展示列表数据之前先获取到 本次选择的角色所拥有的权限的ID 并且只获取 三级权限即可
      // 2.定义一个递归函数 删选出所有三级的权限，并且都存储到一个数组中
      // 3.利用文档给的方法default-expanded-keys 给他赋值一个数组即可显示当前的被选中的权限
      this.screenRightsArr(role, this.defKeys);
      //   console.log(node);Î
      //   展示对话框
      this.getRightsDialog = true;
    },
    // 定义一个递归函数来筛选三级权限
    screenRightsArr(node, arr) {
      // 判断是不是三级权限 如果没有children属性 则说明是三级权限，直接添加到数组中
      if (!node.children) {
        return arr.push(node.id);
      }
      //   如果不是三级权限继续遍历，然后让让每一项再调用筛选的函数
      node.children.forEach(element => this.screenRightsArr(element, arr));
    },
    // 点击取消按钮将数据重置 ，关闭对话框
    cencelChengeRightsList() {
      // 将之前获取的数据清空
      this.defKeys = [];
      this.getRightsDialog = false;
    },
    // 点击确认按钮给角色重新分配权限
    async allotRights() {
      // 利用tree 的引用调用相应的方法获取到权限ID的列表
      const keys = [...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys()];
      //   console.log(keys);
      const keysStr = keys.join(',');
      //   console.log(keysStr);
      // 发送请求
      const data = await this.$http.post(`roles/${this.roleId}/rights`, { rids: keysStr });
      if (!data) this.$message.success('分配权限成功！');
      //   重新刷新权限列表
      this.getRolesList();
      // 关闭对话框
      this.getRightsDialog = false;
    },
    // 定义编辑角色的函数
    async editRolesButton(roles) {
      // 将当前点击的行接收过来,获取到当前角色的数据
      // 将当前角色先赋值给对象
      this.editrolesObj = roles;
      // console.log(this.editrolesObj);
      // 发送请求获取所有的角色信息
      const data = await this.$http.get('roles');
      // console.log(data);
      this.rolesList = data;
      this.editDialogVisible = true;
    },
    // 点击取消选择选择角色的按钮
    cancelRolesChenge() {
      // 将选中的角色id 清空
      this.setRoleId = '';
      // 关闭对话框
      this.editDialogVisible = false;
    },
    // 点击编辑角色的确定按钮
    async confirmRolesChenge() {
      if (!this.setRoleId) return this.$message.info('请选择要修改的角色');
      // 当前选中的角色名
      let newRoleName = '';
      this.rolesList.forEach(item => {
        if (item.id === this.setRoleId) {
          newRoleName = item.roleName;
        }
      });
      // console.log(newRoleName, this.setRoleId);
      // 发送请求
      const data = await this.$http.put('roles/' + this.editrolesObj.id, { roleName: newRoleName });
      // console.log(data);
      if (!data) this.$message.err('修改数据失败！');
      this.$message.success('修改数据成功！');
      // 重新渲染数据列表
      this.getRolesList();
      this.editDialogVisible = false;
    }
  }
};
</script>

<style lang="less" scoped>
.el-tag {
  margin: 7px;
}
.bborder {
  border-bottom: 1px solid #eee;
}
.tboeder {
  border-top: 1px solid #eee;
}
.tcente {
  display: flex;
  align-items: center;
}
</style>
